/**
 * Iterative Lengthening algorithm implementation
 * 
 * @author Taivo Teder
 * @version 1.0
 */

public class Start {
	
	public static void main(String[] args){
//		String start = "Arad";
//		String end = "Oradea";
		String start = "1";
		String end = "2";

		Graph graph = new Graph();
//		printAdjacentMatrix(graph);
		System.out.println("Problem space nodes aka towns: " + graph.size);
		/* Iterative lengthening search*/
		printSearchStrategyDescription("Iterative lengthening");
		IterativeLengthening it = new IterativeLengthening();
		it.setGraph(new Graph(graph));
		long beginTime = System.currentTimeMillis();
		Node solution = it.solve(start, end);
		long endTime = System.currentTimeMillis();
		long elapsed = endTime - beginTime;
		
		printSolutionMessage(solution, it, elapsed);

//		/* Breadth-first search */
//		printSearchStrategyDescription("Breadth-first search");
//		BreadthFirstSearch bfs = new BreadthFirstSearch();
//		bfs.setGraph(new Graph(graph));
//		long beginTime2 = System.currentTimeMillis();
//		Node solution2 = bfs.solve(start, end);
//		long endTime2 = System.currentTimeMillis();
//		long elapsed2 = endTime2 - beginTime2;
//		
//		Node node2 = new Node();
//		node2 = solution2;
//		int solution2Length = 0;
//		while (node2 != null) {
//			solution2Length++;
//			solution2PathCost += node2.getCost();
//			node2 = node2.getParent();
//		}
//		printSolutionMessage(solution2, bfs,elapsed2, solution2Length);

		/* Uniform-cost search */
		printSearchStrategyDescription("Uniform-cost search");
		UniformCostSearch ucs = new UniformCostSearch();
		ucs.setGraph(new Graph(graph));
		long beginTime3 = System.currentTimeMillis();
		Node solution3 = ucs.solve(start, end);
		long endTime3 = System.currentTimeMillis();
		long elapsed3 = endTime3 - beginTime3;

		printSolutionMessage(solution3, ucs, elapsed3);
	}
	
	public static void printAdjacentMatrix (Graph graph) {
		System.out.print("\t|");
		for(Node node : graph.getNodes()) {
			System.out.print("\"" + node.getContent() + "\"" + "\t");
		}
		System.out.println("");
		for(int i = 0; i < graph.getNodes().size()+1; i++) {
			System.out.print("--------");
		}
		
		int[][] adjMatrix = graph.getAdjacentMatrix();
		System.out.println("");
		
		for (int i = 0; i < graph.size; i++){
			System.out.print("\"" + graph.getNodes().get(i).getContent() + "\"" +"\t| ");
			for (int j = 0; j < graph.size; j++){
				System.out.print(adjMatrix[i][j] + " \t");
			}
			System.out.println("");
		}
	}
	
	public static void printSearchStrategyDescription(String searchStrategyName) {
		System.out.println("");
		System.out.println(searchStrategyName);
		System.out.println("=======================================;");
	}
	
	public static void printSolutionMessage(Node solution, Search search, double duration) {
		if(search instanceof IterativeLengthening) {
			if(solution != null) {
				System.out.println("Successful");
				System.out.println("Last iteration nodes visited: " + search.getVisited().size());
				System.out.println("Overall nodes visited: " + ((IterativeLengthening) search).getCount());
				System.out.println("Iterations: " + ((IterativeLengthening) search).getIterations());
			} else {
				System.out.println("Unsuccessful");
			}
			System.out.println("Duration: " + duration);
		} else {
			if(solution != null){
				System.out.println("Successful, visited: " + search.getVisited().size());
			} else {
				System.out.println("Unsuccesful");
			}
			System.out.println("Duration: " + duration);
		}
		System.out.println("Solution length: " + solution.getCost());
	}
}

